package vn.edu.hcmut.cse.ai.search.problems.waterjug;
public class WaterState {

    public static int sizeJug1;
    public static int sizeJug2;
    private int startJug1;
    private int startJug2;
    private int undoJug1;
    private int undoJug2;

    public WaterState(int jug1, int jug2) {
        this.startJug1 = jug1; //Binh 1 = 4l
        this.startJug2 = jug2;
    }

    public WaterState(WaterState copState) {
        this(copState.getJug1(), copState.getJug2());
    }

    @Override
    public int hashCode() {
        int hash = 10;
        hash = 41 * hash + 10 * this.startJug1 + this.startJug2;
        //hash = 41 * hash + this.startJug2;
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final WaterState state = (WaterState) obj;
        if ((this.startJug1 == state.getJug1()) && (this.startJug2 == state.getJug2())) {
            return true;
        } else {
            return false;
        }
    }

    public boolean empty1() {
        if (startJug1 > 0) {
            undoJug1 = startJug1;
            startJug1 = 0;
            return true;
        } else {
            return false;
        }
    }

    public void undoEmpty1() {
        startJug1 = undoJug1;
    }

    public boolean empty2() {
        if (startJug2 > 0) {
            undoJug2 = startJug2;
            startJug2 = 0;
            return true;
        } else {
            return false;
        }
    }

    public void undoEmpty2() {
        startJug2 = undoJug2;
    }

    public boolean fill1() {
        if (startJug1 < sizeJug1) {
            undoJug1 = startJug1;
            startJug1 = sizeJug1;
            return true;
        } else {
            return false;
        }
    }

    public void undoFill1() {
        startJug1 = undoJug1;
    }

    public boolean fill2() {
        if (startJug2 < sizeJug2) {
            undoJug2 = startJug2;
            startJug2 = sizeJug2;
            return true;
        } else {
            return false;
        }
    }

    public void undoFill2() {
        startJug2 = undoJug2;
    }

    public boolean fill1from2() {
        if (((startJug1 + startJug2) >= sizeJug1) && (startJug2 > 0) && (startJug1 < sizeJug1)) {
            undoJug1 = startJug1;
            undoJug2 = startJug2;
            startJug2 = startJug2 - (sizeJug1 - startJug1);
            startJug1 = sizeJug1;
            return true;
        } else {
            return false;
        }
    }

    public void undoFill1From2() {
        startJug1 = undoJug1;
        startJug2 = undoJug2;
    }

    public boolean fill2from1() {
        if (((startJug1 + startJug2) >= sizeJug2) && (startJug1 > 0) && (startJug2 < sizeJug2)) {
            undoJug1 = startJug1;
            undoJug2 = startJug2;
            startJug1 = startJug1 - (sizeJug2 - startJug2);
            startJug2 = sizeJug2;
            return true;
        } else {
            return false;
        }
    }

    public void undoFill2From1() {
        startJug1 = undoJug1;
        startJug2 = undoJug2;
    }

    public boolean pourAll2to1() {
        if (((startJug1 + startJug2) <= sizeJug1) && (startJug2 > 0)) {
            undoJug1 = startJug1;
            undoJug2 = startJug2;
            startJug1 = startJug1 + startJug2;
            startJug2 = 0;
            return true;
        } else {
            return false;
        }
    }

    public void undoPourAll2to1() {
        startJug1 = undoJug1;
        startJug2 = undoJug2;
    }

    public boolean pourAll1to2() {
        if (((startJug1 + startJug2) <= sizeJug2) && (startJug1 > 0)) {
            undoJug1 = startJug1;
            undoJug2 = startJug2;
            
            startJug2 = startJug1 + startJug2;
            startJug1 = 0;
            return true;
        } else {
            return false;
        }
    }

    public void undoPourAll1to2() {
        startJug1 = undoJug1;
        startJug2 = undoJug2;
    }

    public void clearUndo() {
        undoJug1 = 0;
        undoJug2 = 0;
    }

    public int getJug1() {
        return startJug1;
    }

    public int getJug2() {
        return startJug2;
    }
}
